#!/usr/bin/env python3
# utils/log_utils.py
# 日志和监控工具
import time
import numpy as np
import datetime
import logging

from config import SAVE_LOG_BAG

logger = logging.getLogger(__name__)


def monitor_robots_status(server):
    """监控机器人状态"""
    if SAVE_LOG_BAG:
        if not hasattr(server, "logbag_file"):
            server.logbag_file = open("pursuit_logbag.txt", "w")
    while True:
        time.sleep(4)
        status_report = ["\n===== 机器人状态监控 ====="]
        status_report.append(f"任务状态: {'进行中' if server.game_active else '暂停'}")
        status_report.append(f"捕获次数: {server.policy.get_capture_count()}")
        # 信念摘要
        belief_pr = server.policy.get_belief_pr()
        belief_pos = server.policy.get_belief_pos()
        support_count = np.sum(belief_pos)
        entropy = (
            -np.sum(belief_pr[belief_pos] * np.log2(belief_pr[belief_pos] + 1e-10))
            if support_count > 0
            else 0.0
        )
        status_report.append(f"信念支持位置数: {support_count}, 熵: {entropy:.2f}")
        if server.evader:
            info = server.evader.get_info()
            status_report.append(f"逃逸者 {info['id']}:")
            status_report.append(
                f"  位置: {info['position']} | 初始位置: {info['initial_position']} | 节点: {info['node']}"
            )
            status_report.append(
                f"  目标: {info['target']} | 目标节点: {info['target_node']}"
            )
            status_report.append(
                f"  状态: {info['status']} | 最后更新: {info['last_update']:.1f}秒前"
            )
            status_report.append(f"  最后心跳: {info['last_heartbeat']:.1f}秒前")
        else:
            status_report.append("逃逸者: 未连接")
        for robot_id in [1, 2]:
            robot = server.pursuers.get(robot_id)
            if robot:
                info = robot.get_info()
                status_report.append(f"追捕者 {info['id']}:")
                status_report.append(
                    f"  位置: {info['position']} | 初始位置: {info['initial_position']} | 节点: {info['node']}"
                )
                status_report.append(
                    f"  目标: {info['target']} | 目标节点: {info['target_node']}"
                )
                status_report.append(
                    f"  状态: {info['status']} | 最后更新: {info['last_update']:.1f}秒前"
                )
                status_report.append(f"  最后心跳: {info['last_heartbeat']:.1f}秒前")
            else:
                status_report.append(f"追捕者 {robot_id}: 未连接")
        status_report.append("=" * 30)
        logger.info("\n".join(status_report))
        # Logbag
        if SAVE_LOG_BAG and hasattr(server, "logbag_file"):
            timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")[:-3]
            coord_parts = []
            # Evader
            ex, ey = (
                server.evader.current_position
                if server.evader and server.evader.current_position
                else (-1, -1)
            )
            coord_parts.append(f"evader:({ex:.2f},{ey:.2f})")
            # Pursuers
            for rid in [1, 2]:
                robot = server.pursuers.get(rid)
                px, py = (
                    robot.current_position
                    if robot and robot.current_position
                    else (-1, -1)
                )
                coord_parts.append(f"p{rid}:({px:.2f},{py:.2f})")
            coord_str = " ".join(coord_parts)
            belief_str = ""
            belief_pos_active = np.where(belief_pos)[0]
            if len(belief_pos_active) > 0:
                belief_items = [
                    f"n{node}:{belief_pr[node]:.3f}" for node in belief_pos_active
                ]
                belief_str = " ".join(belief_items)
            line = f"[{timestamp}] {coord_str}"
            if belief_str:
                line += f" [{belief_str}]"
            server.logbag_file.write(line + "\n")
            server.logbag_file.flush()
        # 强制触发策略
        if server.game_active:
            server.node_change_event.set()
            logger.debug("[Monitor] 定期强制触发策略计算")
        # 清理断开机器人
        if (
            server.evader
            and not server.evader.is_active()
            and server.evader.status == "disconnected"
        ):
            server.evader = None
            logger.info("[清理] 逃逸者已断开")
        to_remove = [
            rid
            for rid, robot in server.pursuers.items()
            if not robot.is_active() and robot.status == "disconnected"
        ]
        for rid in to_remove:
            del server.pursuers[rid]
            logger.info(f"[清理] 追捕者 {rid} 已断开")
        # 更新任务状态
        server.check_game_state()
